/**
 * --------------------------------------------------------------------------
 * 工具提示
 * Hi.js (v1.0.0): tooltip.js
 * 2020-03-05 13:17:50
 * require jquery
 * --------------------------------------------------------------------------
 */
;
(function($, window, document, undefined) {
    'use strict';

    function init(target) {
        $(target).addClass('tooltip-f');
    }

    function setSize(target, param) {
        var opts = $.data(target, 'tooltip')
        var options = opts.options;
        $(target).unbind('.tooltip').bind(options.showEvent + '.tooltip', function(e) {
            $(target).tooltip('show', e);
        }).bind(options.hideEvent + '.tooltip', function(e) {
            $(target).tooltip('hide', e);
        }).bind('mousemove.tooltip', function(e) {
            if (options.trackMouse) {
                options.trackMouseX = e.pageX;
                options.trackMouseY = e.pageY;
                $(target).tooltip('reposition', e);
            }
        });
    }

    function show(target, param) {
        var opts = $.data(target, 'tooltip');
        var options = opts.options;
        var tip = opts.tip;
        if (!tip) {
            tip = $('<div tabindex="-1" class="tooltip">' +
                '<div class="tooltip-arrow"></div>' +
                '<div class="tooltip-content"></div>' + '</div>').appendTo("body");
            opts.tip = tip;
            update(target);
        }
        clearTimer(target);
        opts.showTimer = setTimeout(() => {
            $(target).tooltip('reposition');
            tip.show();
            options.onShow.call(target, param);

            var $arrow = tip.children('.tooltip-arrow');
            var $content = tip.children('.tooltip-content');
            var bc = 'tooltip-' + options.position;
            tip.addClass(bc + (options.className && (' ' + options.className)));
            $arrow.css('border-' + options.position + '-color', options.color);
            $content.css('background-color', options.color);
        }, options.showDelay);
    }

    function hide(target, param) {
        var opts = $.data(target, 'tooltip');
        if (opts && opts.tip) {
            clearTimer(target);
            opts.hideTimer = setTimeout(function() {
                opts.tip.hide();
                opts.options.onHide.call(target, param);
            }, opts.options.hideDelay);
        }
    }

    function clearTimer(target) {
        var opts = $.data(target, 'tooltip');
        if (opts.showTimer) {
            clearTimeout(opts.showTimer);
            opts.showTimer = null;
        }
        if (opts.hideTimer) {
            clearTimeout(opts.hideTimer);
            opts.hideTimer = null;
        }
    }

    function reposition(target, param) {
        var opts = $.data(target, 'tooltip');
        if (!opts || !opts.tip) {
            return;
        }
        var options = opts.options;
        var tip = opts.tip;
        var position = {
            left: -100000,
            top: -100000
        }
        if ($(target).is(':visible')) {
            position = setPosition(options.position);
            if (options.position == 'top' && position.top < 0) {
                position = setPosition('bottom');
            } else {
                if ((options.position == 'bottom') && (position.top + tip.outerHeight() > $(window).outerHeight() + $(document).scrollTop())) {
                    position = setPosition('top');
                }
            }
            if (position.left < 0) {
                if (options.position == 'left') {
                    position = setPosition('right');
                } else {
                    $(target).tooltip('arrow').css('left', tip.outerWidth() / 2 + position.left);
                    position.left = 0;
                }
            } else {
                if (position.left + tip.outerWidth() > $(window).outerWidth() + $(document).scrollLeft()) {
                    if (options.position == 'right') {
                        position = setPosition('left');
                    } else {
                        var left = position.left;
                        position.left = $(window).outerWidth() + $(document).scrollLeft() - tip.outerWidth();
                        $(target).tooltip('arrow').css('left', tip.outerWidth() / 2 - (position.left - left));
                    }
                }
            }
        }
        tip.css({ left: position.left, top: position.top, zIndex: (options.zIndex != undefined ? _c.zIndex : ($.fn.window ? $.fn.window.defaults.zIndex++ : '')) });
        options.onPosition.call(target, position.left, position.top);

        function setPosition(position) {
            options.position = position || 'bottom';
            tip.removeClass('tooltip-top tooltip-right tooltip-bottom tooltip-left').addClass('tooltip-' + options.position);
            var trackMouseX, top;
            var deltaX = $.isFunction(options.deltaX) ? options.deltaX.call(target, options.position) : options.deltaX;
            var deltaY = $.isFunction(options.deltaY) ? options.deltaY.call(target, options.position) : options.deltaY;
            if (options.trackMouse) {
                $element = $();
                trackMouseX = options.trackMouseX + deltaX;
                top = options.trackMouseY + deltaY;
            } else {
                var $element = $(target);
                trackMouseX = $element.offset().left + deltaX;
                top = $element.offset().top + deltaY;
            }
            switch (options.position) {
                case 'top':
                    trackMouseX -= (tip.outerWidth() - $element.outerWidth()) / 2;
                    top -= $element.outerHeight() + 5 + (options.trackMouse ? $(target).outerHeight() : 0);
                    break;
                case 'right':
                    trackMouseX += $element.outerWidth() + 12 + (options.trackMouse ? 12 : 0);
                    if (options.valign == 'middle') {
                        top -= (tip.outerHeight() - $element.outerHeight()) / 2;
                    }
                    break;
                case 'bottom':
                    trackMouseX -= (tip.outerWidth() - $element.outerWidth()) / 2;
                    top += $element.outerHeight() + 12 + (options.trackMouse ? 12 : 0);
                    break;
                case 'left':
                    trackMouseX -= tip.outerWidth() + 12 + (options.trackMouse ? 12 : 0);
                    if (options.valign == 'middle') {
                        top -= (tip.outerHeight() - $element.outerHeight()) / 2;
                    }
                    break;
            }
            return {
                left: trackMouseX,
                top: top
            }
        }
    }

    function update(target, param) {
        var opts = $.data(target, 'tooltip');
        var options = opts.options;
        if (param) {
            options.content = param;
        }
        if (!opts.tip) {
            return;
        }
        var content = typeof options.content == 'function' ? options.content.call(target) : options.content;
        opts.tip.children('.tooltip-content').html(content);
        options.onUpdate.call(target, content);
    }

    function destroy(target) {
        var opts = $.data(target, 'tooltip');
        if (opts) {
            clearTimer(target);
            var options = opts.options;
            if (opts.tip) {
                opts.tip.remove();
            }
            if (options.title) {
                $(target).attr('title', options.title);
            }
            $.removeData(target, 'tooltip');
            $(target).unbind('.tooltip').removeClass('tooltip-f');
            options.onDestroy.call(target);
        }
    }

    $.fn.tooltip = function(options, param) {
        if (typeof options == 'string') {
            return $.fn.tooltip.methods[options](this, param);
        }
        options = options || {};
        return this.each(function() {
            var state = $.data(this, 'tooltip');
            if (state) {
                $.extend(state.options, options);
            } else {
                $.data(this, 'tooltip', {
                    options: $.extend({}, $.fn.tooltip.defaults, $.fn.tooltip.parseOptions(this), options)
                })
                init(this);
            }
            setSize(this);
            update(this);
        });
    };

    $.fn.tooltip.VERSION = '1.0.0';

    $.fn.tooltip.methods = {
        options: function(jq) {
            return $.data(jq[0], 'tooltip').options;
        },
        tip: function(jq) {
            return $.data(jq[0], 'tooltip').tip;
        },
        arrow: function(jq) {
            return jq.tooltip('tip').children('.tooltip-arrow');
        },
        show: function(jq, param) {
            return jq.each(function() {
                show(this, param)
            });
        },
        hide: function(jq, param) {
            return jq.each(function() {
                hide(this, param);
            });
        },
        update: function(jq, param) {
            return jq.each(function() {
                update(this, param);
            });
        },
        reposition: function(jq, param) {
            return jq.each(function() {
                reposition(this, param);
            });
        },
        destroy: function(jq, param) {
            return jq.each(function() {
                destroy(this, param);
            });
        }
    };

    $.fn.tooltip.parseOptions = function(target) {
        var $element = $(target);
        var options = $.extend({}, $.parser.parseOptions($element, ['position', 'showEvent', 'hideEvent', 'content'], {
            trackMouse: 'boolean',
            deltaX: 'number',
            deltaY: 'number',
            showDelay: 'number',
            hideDelay: 'number'
        }), {
            _title: $element.attr('title')
        });
        $element.attr('title', '');
        if (!options.content) {
            options.content = options.title || options._title;
        }
        return options;
    }

    $.fn.tooltip.defaults = {
        position: 'bottom',
        valign: 'middle',
        color: '#000',
        className: '',
        content: null,
        trackMouse: false,
        deltaX: 0,
        deltaY: 0,
        showEvent: 'mouseenter',
        hideEvent: 'mouseleave',
        showDelay: 200,
        hideDelay: 100,
        onShow: $.noop,
        onHide: $.noop,
        onUpdate: $.noop,
        onPosition: $.noop,
        onDestroy: $.noop
    };

    setTimeout(function() {
        $('[data-toggle=tooltip]').tooltip();
    }, 0);

})(jQuery, window, document);